#include "String.h"

SGF::String::String()
{
	_string = NULL;
	_length = 0;
}
SGF::String::String(UInt64 length, UInt8 c)
{
	_string = new UInt8[length];
	for (UInt64 i = 0; i < length; i++)
	{
		_string[i] = c;
	}
	_length = length;
}
SGF::String::String(const String& src)
{
	if (src._length == 0)
	{
		_length = 0;
		_string = NULL;
	}
	else
	{
		_length = src._length;
		_string = new UInt8[_length];
		for (UInt64 i = 0; i < _length; i++)
		{
			_string[i] = src._string[i];
		}
	}
}
SGF::String::String(UInt8* src)
{
	if (src == NULL)
	{
		_length = 0;
		_string = NULL;
	}
	else
	{
		UInt64 size = 0;
		while (src[size] != '\0')
		{
			size++;
		}
		_string = new UInt8[size];
		for (UInt64 i = 0; i < size; i++)
		{
			_string[i] = src[i];
		}
		_length = size;
	}
}

SGF::String::String( char* src )
{
	if (src == NULL)
	{
		_length = 0;
		_string = NULL;
	}
	else
	{
		UInt64 size = 0;
		while (src[size] != '\0')
		{
			size++;
		}
		_string = new UInt8[size];
		for (UInt64 i = 0; i < size; i++)
		{
			_string[i] = src[i];
		}
		_length = size;
	}
}SGF::String::~String()
{
	if (_string != NULL)
	{
		delete[] _string;
	}
}

SGF::String& SGF::String::operator=(const String& src)
{
	Clear();
	if (src._length == 0)
	{
		_length = 0;
		_string = NULL;
	}
	else
	{
		_length = src._length;
		_string = new UInt8[_length];
		for (UInt64 i = 0; i < _length; i++)
		{
			_string[i] = src._string[i];
		}
	}
	return * this;
}

SGF::String& SGF::String::operator=(UInt8* src)
{
	if (src == NULL)
	{
		_length = 0;
		_string = NULL;
	}
	else
	{
		UInt64 size = 0;
		while (src[size] != '\0')
		{
			size++;
		}
		_string = new UInt8[size];
		for (UInt64 i = 0; i < size; i++)
		{
			_string[i] = src[i];
		}
		_length = size;
	}
	return * this;
}

bool SGF::String::operator==(const String& src)
{
	if (_length != src._length)
	{
		return false;
	}
	else
	{
		for (UInt64 i = 0; i < _length; i++)	
		{
			if (_string[i] != src._string[i])
			{
				return false;
			}
		}
		return true;
	}
}

bool SGF::String::operator==(UInt8* src )
{
	UInt64 size = 0;
	while (src[size] != '\0')
	{
		size++;
	}
	if (_length != size)
	{
		return false;
	}
	else
	{
		for (UInt64 i = 0; i < _length; i++)	
		{
			if (_string[i] != src[i])
			{
				return false;
			}
		}
		return true;
		
	}
}

bool SGF::String::operator!=( const String& src )
{
	return !(*this == src);
}

bool SGF::String::operator!=( UInt8* src )
{
	return !(*this == src);
}
SGF::UInt8& SGF::String::operator[](UInt64 index)
{
	if ((index >= 0) && (index < _length))
	{
		return _string[index];
	}
	else
	{
		throw 10;
	}
}

SGF::String SGF::String::operator+(const String& src)
{
	SGF::String s;

	if (src._length == 0)
	{
		s = *this;
		return s;
	}

	if (_length == 0)
	{
		s = src;
		return s;
	}
	
	s._length = _length + src._length;
	s._string = new UInt8[s._length];
	for (UInt64 i = 0; i < _length; i++)
	{
		s._string[i] = _string[i];
	}
	for (UInt64 i = 0; i < src._length; i++)
	{
		s._string[i + _length] = src._string[i];
	}
	return s;
}

SGF::String SGF::String::operator+(UInt8* src)
{
	UInt64 size = 0;
	while (src[size] != '\0')
	{
		size++;
	}
	SGF::String s;

	if (size == 0)
	{
		s = *this;
		return s;
	}

	if (_length == 0)
	{
		s = src;
		return s;
	}
	s._length = _length + size;
	s._string = new UInt8[s._length];
	for (UInt64 i = 0; i < _length; i++)
	{
		s._string[i] = _string[i];
	}
	for (UInt64 i = 0; i < size; i++)
	{
		s._string[i + _length] = src[i];
	}
	return s;

}

SGF::String& SGF::String::operator+=(const String& src)
{
	if (src._length == 0)
	{
		return* this;
	}

	if (_length == 0)
	{
		*this = src;
		return* this;
	}

	UInt64 length = _length + src._length;
	UInt8* str = new UInt8[length];

	for (UInt64 i = 0; i < _length; i++)
	{
		str[i] = _string[i];
	}
	for (UInt64 i = 0; i < src._length; i++)
	{
		str[i + _length] = src._string[i];
	}
	Clear();
	_length = length;
	_string = str;
	return* this;
}

SGF::String& SGF::String::operator+=(UInt8* src)
{
	UInt64 size = 0;
	while (src[size] != '\0')
	{
		size++;
	}

	if (size == 0)
	{
		return* this;
	}

	if (_length == 0)
	{
		*this = src;
		return* this;
	}

	UInt64 length = _length + size;
	UInt8* str = new UInt8[length];
	for (UInt64 i = 0; i < _length; i++)
	{
		str[i] = _string[i];
	}
	for (UInt64 i = 0; i < size; i++)
	{
		str[i + _length] = src[i];
	}
	Clear();
	_length = length;
	_string = str;
	return* this;
}

SGF::UInt64 SGF::String::GetLength()
{
	return _length;
}
SGF::UInt8* SGF::String::String2Char(const String& src)
{
	UInt8* str = new UInt8[src._length + 1];
	for(UInt64 i = 0; i < src._length; i++)
	{
		str[i] = src._string[i];
	}
	str[src._length] = '\0';
	return str;
}

void SGF::String::Print()
{
	for (UInt64 i = 0; i < _length; i++)
	{
		std::cout << _string[i];
	}
}

void SGF::String::Clear()
{
	delete[] _string;
	_length = 0;
}

std::ostream& SGF::operator<<( std::ostream& stream, SGF::String& src )
{
	for (UInt64 i = 0; i < src._length; i++)
	{
		stream << src._string[i];
	}
	return stream;
}